from django.views import View
from libs.captcha.captcha import captcha
from django_redis import get_redis_connection
from django.http import JsonResponse, HttpResponse
# from libs.yuntongxun.ccp_sms import CCP
from celery_tasks.sms.tasks import send_sms_code
from users.models import User
import json
import random
import re


class ImageCodeView(View):
    def get(self, request):
        # 获取参数
        cur = request.GET.get("cur")
        pre = request.GET.get("pre")
        # 生成图形验证码
        text, image = captcha.generate_captcha()
        # 连接redis数据库
        conn = get_redis_connection("verify_code")
        # 保存图形验证码信息
        conn.setex("img_%s" % cur, 300, text)
        # pre?
        # 删除上一次的图形验证码，释放缓存
        conn.delete("img_%s" % pre)
        # 构建响应
        return HttpResponse(
            image,
            content_type="image/jpg"
        )


class SMSCodeView(View):
    def post(self, request):
        data = json.loads(request.body.decode())
        mobile = data.get("mobile")
        id = data.get("id")
        text = data.get("text")

        # 校验参数
        # 必要性校验
        if not all([mobile, id, text]):
            return JsonResponse({
                "errno": 400,
                "errmsg": "缺少参数"
            })

        # 校验手机号
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({
                'errno': 400,
                'errmsg': '输入mobile格式有误'
            }, status=400)

        # 校验手机号是否已注册
        count = User.objects.filter(mobile=mobile).count()
        if count:
            # 如果已注册，返回
            return JsonResponse({
                "errno": 400,
                "errmsg": "手机号已注册"
            }, status=400)

        # 校验图形验证码格式
        if not re.match(r"[a-zA-Z0-9]{4}$", text):
            return JsonResponse({
                "errno": 400,
                "errmsg": "图形验证码格式有误！"
            }, status=400)

        # 校验图形验证码编号
        if not re.match(r"^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$", id):
            return JsonResponse({
                "errno": 400,
                "errmsg": "id不符合格式"
            }, status=400)

        # 校验用户输入的图形验证码和redis中记录的是否一致
        conn = get_redis_connection("verify_code")
        img_from_redis = conn.get("img_%s" % id)
        # 判断图形验证码是否过期
        if not img_from_redis:
            return JsonResponse({
                "errno": 400,
                "errmsg": "图形验证码失效"
            })

        # 判断用户输入的图形验证码是否有误
        # 忽略大小写
        if img_from_redis.decode().lower() != text.lower():
            return JsonResponse({
                "errno": 400,
                "errmsg": "输入的图形验证码错误"
            })

        # 获取发送标记是否存在
        # 如果存在，返回
        send_flag = conn.get("send_flag_%s" % mobile)
        if send_flag:
            return JsonResponse({
                'errno': 400,
                'errmsg': '不能频繁发送信息'
            })

        # 随机生成短信验证码 --> 例如："021233"
        sms_code = "%06d" % random.randint(0, 999999)
        print(sms_code)

        # 通过pl管道对象，调用执行函数
        pl = conn.pipeline()

        # 保存短信验证码，时效5分钟
        # 设置发送标记位，时效1分钟
        pl.setex("sms_%s" % mobile, 300, sms_code)
        pl.setex("send_flag_%s" % mobile, 60, 1)

        # 批量执行管道中暂存命令
        pl.execute()

        # # 发送短信验证码
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # 将发送短信验证码设置为异步任务
        send_sms_code.delay(mobile, sms_code)
        print("短信验证码：%s" % sms_code)

        # 构建响应
        return JsonResponse({
            "errno": 0,
            "errmsg": "发送成功"
        })